#include "StdAfx.h"
#include ".\boundedfunctiondescription.h"

BoundedFunctionPoints::BoundedFunctionPoints(double RMin, double RMax, size_t IntNum):
XRangeMin(RMin), XRangeMax(RMax), IntervalsNum(IntNum){
	
	ASSERT(RMax > RMin);
	ASSERT(IntervalsNum >= 1);
	step = (RMax - RMin)/(double)IntervalsNum;
	double Curr = RMin;
	(this->operator [](Curr)) = NULL;
	for(size_t i=0; i<this->IntervalsNum; i++){
		Curr += step;
		(this->operator [](Curr)) = NULL;
		}
		
	}

void BoundedFunctionPoints::draw() const{
	glColor3f(1.0f, 0.0f, 0.0f);
	map<double,  F<double>*>::const_iterator Ctr1= begin();
	while((!(Ctr1->second)) && (Ctr1 != end( ))) Ctr1++;
	while(Ctr1 != end( )){
		 map<double,  F<double>*>::const_iterator Ctr2=Ctr1;
		 Ctr2++;
		 while((!(Ctr2->second)) && (Ctr2 != end( ))) Ctr2++;
		 if(Ctr2 != end( )){
		 		glBegin(GL_LINES);			
				glVertex3f(Ctr1->first, Ctr1->second->x( ), 0.1f);
				glVertex3f(Ctr2->first, Ctr2->second->x( ), 0.1f);
				glEnd();			
				}
		 Ctr1=Ctr2;
		}
	}

double BoundedFunctionPoints::x(size_t index) const{
	if(index < 0 || index >= this->PointsNum( )) throw "Out of Bound";
	size_t Ctr = 0;
	map<double,  F<double>*>::const_iterator Ctr1= begin( );
	while(Ctr < index){Ctr++; Ctr1++;}
	return Ctr1->first;
	}

F<double>* BoundedFunctionPoints::Fx(size_t index){
	return this->operator [](x(index));
	}

void BoundedFunctionPoints::setValueAtPoint(double Val, F<double>* TPPtr){
	double halfstep = step/2.0f; 
	if(Val < x(0)-halfstep) return;
	if(Val >= x(PointsNum( )-1) + halfstep) return;

	for(size_t i=0; i<this->PointsNum( ); i++){
		if((Val >= x(i) - halfstep) &&  (Val < x(i) +	 halfstep)){
			  (this->operator [](x(i)))	= TPPtr;
			  return;
			}
	}
}		
F<double>* BoundedFunctionPoints::getValueAtPoint( double Val) {
	double halfstep = step/2.0f; 
	if(Val < x(0)-halfstep) return NULL;
	if(Val >= x(PointsNum( )-1) + halfstep) return NULL;
	map <double, F<double>* >::iterator Ptr= begin( );

	for(size_t i=0; i<this->PointsNum( ); i++)
		if((Val >= x(i) - halfstep) &&  (Val < x(i) +	 halfstep)){
			return   Ptr->second	;
			}
		else{
			Ptr++;
			}
	return NULL;
	}


BoundedFunctionPoints::~BoundedFunctionPoints(void)
	{
	}




BoundedFunctionDescription::BoundedFunctionDescription(
	FuncRep Rep,
	double RMin, 
	double RMax, 
	size_t IntNum):
BoundedFunctionPoints(RMin, RMax, IntNum){
	EvalFunc = Rep.first;
	Syntax = Rep.second;
	
	for(size_t i=0; i < this->PointsNum( ); i++){
		F<double> x_i = x(i);
		x_i.diff(0, 1);
		this->setValueAtPoint(x(i),	 makeBehave((*EvalFunc)(x_i)));

		}
}





F<double>* BoundedFunctionDescription::makeBehave(F<double> y){

	if(fabs(y.x()) < TOL_0){
		F<double>* Ptr = new F<double>(0.0f);
		Ptr->diff(0,1);
		return Ptr;
		}
	
	if (y.x() > OVERFLOW){
		CString Mssg;
		Mssg.Format("OVERFLOW Exception (Evaluates to %f)", y);
		throw(Mssg);
	}

	if (y.x() < UNDERFLOW){
		CString Mssg;
		Mssg.Format("UNDERFLOW Exception (Evaluates to %f)", y);
		throw Mssg;
	}

	return new F<double>(y);
}

BoundedFunctionDescription::~BoundedFunctionDescription( ){
	 map<double, F<double>*>::iterator Ctr1= begin( );	
	 for(;Ctr1 != end( ); Ctr1++)
		if(Ctr1->second){
			delete Ctr1->second;
			Ctr1->second = NULL;
			}
	}






